package org.iabako.client.ui.form.business.sale;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import org.iabako.client.navigation.NavigationController;
import org.iabako.client.tools.IabakoAsyncCallback;
import org.iabako.client.tools.Messages;
import org.iabako.client.ui.form.business.payment.ListPaymentsForm;
import org.iabako.client.ui.layout.widget.dialogbox.IabakoDialogBox;
import org.iabako.client.ui.layout.widget.payment.PaymentTable;
import org.iabako.shared.entity.business.*;
import org.iabako.shared.entity.enumeration.InstallmentsType;
import org.iabako.shared.iservice.business.InstallmentServiceAsync;
import org.iabako.shared.iservice.business.PaymentServiceAsync;
import org.iabako.shared.iservice.business.SaleServiceAsync;
import org.iabako.shared.tools.GenericTools;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Created by jose on 26/08/14.
 */
public class SalePaymentsForm extends ListPaymentsForm {

    Sale sale;
    SaleInvoiceForm saleInvoiceForm;
    List<Payment> paymentsList = new ArrayList<Payment>();
    List<Installment> installmentsList = new ArrayList<Installment>();


    public void setSale(final Sale s, final SaleInvoiceForm invoiceForm) {
        sale = s;
        saleInvoiceForm = invoiceForm;
        final SalePaymentsForm salePaymentsForm = this;

        if (payments == null && installments == null) {
            payments = new PaymentTable(this, sale,
                    PaymentServiceAsync.Util.getInstance(), PaymentServiceAsync.Util.getInstance(),
                    Arrays.asList(paymentToInstallmentAction), false, false) {
                @Override
                protected void customTaskAfterRender() {
                    super.customTaskAfterRender();
                    enableLastCustomActionForPayment();

                    saleInvoiceForm.setInfo(sale, salePaymentsForm);
                }
            };

            installments = new PaymentTable(this, sale,
                    InstallmentServiceAsync.Util.getInstance(), InstallmentServiceAsync.Util.getInstance(),
                    Arrays.asList(installmentToPaymentAction), true, true) {
                @Override
                protected void customTaskAfterRender() {
                    super.customTaskAfterRender();
                    enableFirstCustomActionForInstallment();

                    saleInvoiceForm.calculateGlobalInvoiceVisibility(salePaymentsForm);
                }
            };
        } else {
            refreshPayments();
            refreshInstallments();
        }

        payments.show(paymentsPanel);
        installments.show(installmentsPanel);

        getPaymentsAndInstallments();

        if (sale.getInstallmentsDefinition() != null
                && sale.getInstallmentsDefinition().getInstallmentsType() == InstallmentsType.undefined) {

            disableWarningMessage = true;

            undefinedInstallmentsRecapPanel.setVisible(true);

            calculateUndefinedInstallmentsNote();

            final IabakoDialogBox iabakoDialogBox = new IabakoDialogBox(
                    "stop_undefined_installments_creation_title",
                    "stop_undefined_installments_creation_question", true,
                    "stop_undefined_installments_creation_confirm") {
                @Override
                protected void customConfirmButtonHandler() {
                    saleServiceAsync.stopUndefinedInstallmentsCreation(sale, new IabakoAsyncCallback<Sale>() {

                        public void onSuccess(Sale result) {
                            sale = result;
                            calculateUndefinedInstallmentsNote();
                            super.onSuccess(result);
                        }
                    });
                }
            };

            iabakoDialogBox.setCloseOnlySimplePopup(true);

            undefinedInstallmentsStopCreation.getLabel().addClickHandler(new ClickHandler() {
                public void onClick(ClickEvent event) {
                    NavigationController.getInstance().show(iabakoDialogBox);
                }
            });
        }
    }

    private void calculateUndefinedInstallmentsNote() {

        InstallmentsDefinition iDef = sale.getInstallmentsDefinition();

        if (!GenericTools.isEmpty(iDef.getStopUndefinedInstallmentsString(), iDef.getLastUndefinedInstallmentString())) {

            undefinedInstallmentsStopCreation.setVisible(false);
            undefinedInstallmentsNote.setLabel(Messages.getLabel("sale_modify_stopped_undefined_installments_note1",
                    GenericTools.formatDate(GenericTools.getDateFromString(iDef.getStopUndefinedInstallmentsString())),
                    GenericTools.formatDate(GenericTools.getDateFromString(iDef.getLastUndefinedInstallmentString()))));

        } else if (!GenericTools.isEmpty(iDef.getStopUndefinedInstallmentsString())) {

            undefinedInstallmentsStopCreation.setVisible(false);
            undefinedInstallmentsNote.setLabel(Messages.getLabel("sale_modify_stopped_undefined_installments_note2",
                    GenericTools.formatDate(GenericTools.getDateFromString(iDef.getStopUndefinedInstallmentsString()))));

        } else {
            undefinedInstallmentsStopCreation.setVisible(true);
            undefinedInstallmentsNote.setLabel(Messages.getLabel("sale_modify_undefined_installments_note",
                    iDef.getInstallmentsPeriodicalFrequencyN() + "",
                    iDef.getInstallmentsPeriodicalFrequency().getLabel(),
                    GenericTools.formatDate(iDef.getInstallmentsPeriodicalStartDate()),
                    GenericTools.formatAmount(iDef.getInstallmentsPeriodicalPrice() + ""),
                    GenericTools.formatDate(iDef.getNextUndefinedInstallment())));
        }
    }

    protected void getPaymentsAndInstallments() {
        SaleServiceAsync.Util.getInstance().getPayments(sale, new IabakoAsyncCallback<List<Payment>>() {
            public void onSuccess(List<Payment> result) {
                sale.setPayments(result);
                paymentsList = result;

                SaleServiceAsync.Util.getInstance().getInstallments(sale, new IabakoAsyncCallback<List<Installment>>() {
                    public void onSuccess(List<Installment> result) {
                        sale.setInstallments(result);
                        installmentsList = result;
                        paymentResume.setInformation(sale, paymentsList, installmentsList);
                        super.onSuccess(result);
                    }
                });

                super.onSuccess(result);
            }
        });
    }

    @Override
    protected void customSuccessTransferAction() {
        getPaymentsAndInstallments();
        saleInvoiceForm.setInfo(sale, this);
    }

    public void refreshPayment(Payment payment) {
        refreshObjectToList(payment, paymentsList);
    }

    public void refreshInstallment(Installment installment) {
        refreshObjectToList(installment, installmentsList);
    }

    public void refreshObjectToList(AbstractEntity entity, List entitiesList) {
        int index = -1;
        for (Object e : entitiesList) {
            if ((((AbstractEntity) e).getId()).equals(entity.getId())) {
                //It's a payment modification
                index = entitiesList.indexOf(e);
                break;
            }
        }
        if (index >= 0) {
            //It's a payment modification
            entitiesList.set(index, entity);
        } else {
            //It's a payment creation
            entitiesList.add(entity);
        }
        paymentResume.setInformation(sale, paymentsList, installmentsList);
    }

    public void deletePayment(Long idDeletedPayment) {
        Payment paymentToDelete = null;
        for (Payment payment : paymentsList) {
            if (payment.getId().equals(idDeletedPayment)) {
                paymentToDelete = payment;
            }
        }
        paymentsList.remove(paymentToDelete);
        paymentResume.setInformation(sale, paymentsList, installmentsList);
        saleInvoiceForm.setInfo(sale, this);
    }

    public void deleteInstallment(Long idDeletedInstallment) {
        Installment installmentToDelete = null;
        for (Installment installment : installmentsList) {
            if (installment.getId().equals(idDeletedInstallment)) {
                installmentToDelete = installment;
            }
        }
        installmentsList.remove(installmentToDelete);
        paymentResume.setInformation(sale, paymentsList, installmentsList);
    }

    public Sale getSale() {
        return sale;
    }
}
